#ifndef CURLING_RENDERER_INCLUDED
#define CURLING_RENDERER_INCLUDED

#include <string>
#include <vector>
#include <map>
#include <boost/shared_ptr.hpp>
#include "opengl.hpp"
#include <fmod.hpp>
#include "config.hpp"

namespace curling {

class gui;
class rink;
class stone;
class texture_font_t;
class Start_Menu_Textures;
class game;
class character_t;

/**
 * Renderer for a single curling stone.
 */
class stone_renderer_t
{
public:
  
  stone_renderer_t(
    boost::shared_ptr<stone> s,
    FMOD::System* fmod_system,
    FMOD::Sound* slide_sound );
  ~stone_renderer_t();
    
  void render( double t, double dt );
  
private:
  
  boost::shared_ptr<stone> _stone;
  FMOD::System* _fmod_system;
  FMOD::Sound* _fmod_slide_sound;
  FMOD::Channel* _fmod_slide_channel;
};

/**
 * User Interface Renderer
 */
class renderer
{
public:
  
  renderer( boost::shared_ptr<gui> gui );
  ~renderer();
  
  void render( double t, double dt );
  void render_gui( double t, double dt );
  void render_fps( double t, double dt );
  void render_credits_screen( double t, double dt );
  void render_main_menu( double t, double dt );
  void render_start_menu( double t, double dt );
  void render_options_menu( double t, double dt );
  void render_game_menu( double t, double dt );
  void render_scoreboard( double t, double dt );
  void render_scoreboard_team( double t, double dt, bool red );
  void render_message( double t, double dt );
  void render_winner_screen( double t, double dt );
  void render_powermeter( double t, double dt );
  void update_camera( double t, double dt );
  void render_arena( double t, double dt );
  void render_rink( boost::shared_ptr<rink> rink, double t, double dt );
  void render_rink_wall( double t, double dt, double length );
  void render_stone( boost::shared_ptr<stone> stone, double t, double dt );
  void render_floor( double t, double dt );
  void render_characters( double t, double dt );
  void render_character( boost::shared_ptr<character_t> c, double t, double dt );
  void render_menu_background( double t, double dt );
  
  /**
   * Renderar läktare o dyl, vafasen det nu kallas på engelska.
   */
  void render_lower_standard_section( double length, double t, double dt );
  void render_lower_corner_section( double t, double dt );
  void render_upper_standard_section( double length, double t, double dt );
  void render_upper_corner_section( double t, double dt );
  
  void render_sections( double t, double dt );
  void render_section_base( double t, double dt );
  void render_standard_section( double t, double dt, int rows );
  void render_corner_section( double t, double dt, int rows );
  void render_bar( double t, double dt, double length );
  void render_ceiling( double t, double dt );
  void render_mediacube( double t, double dt);
  void render_seats( double t, double dt, int n );
  void render_seat( double t, double dt );
  
  /** Event from GUI that it is starting to play the title music. */
  void play_title_music_event();
  /** Event from GUI that it is stopping the title music. */
  void stop_title_music_event();
  
  void start_arena_sound_event();
  void stop_arena_sound_event();
  
  void focus_item_event();
  void select_item_event();
  
  void stone_stone_collision_event(
    boost::shared_ptr<stone> s1,
    boost::shared_ptr<stone> s2,
    double impact_velocity );
  
  void game_attached_event( boost::shared_ptr<game> g );
  void game_detached_event( boost::shared_ptr<game> g );
    
private:
  
  boost::shared_ptr<gui> _gui;
  boost::shared_ptr<class renderer_gui_listener_t> _gui_listener;
  boost::shared_ptr<texture_font_t> _font;
  boost::shared_ptr<Start_Menu_Textures> _startMenu;
  double _fps_basetime;
  double _fps_frames;
  std::string _fps_string;
  
  GLuint _credits_texture;
  GLuint _seata_texture;
  GLuint _seatb_texture;
  GLuint _ice_texture;
  GLuint _floor_texture;
  GLuint _marble_texture;
  GLuint _champs_texture;
  GLuint _glow_texture;
  GLuint _title_texture;
  GLuint _crowd_texture;
  GLuint _curlingborder_texture;
  GLuint _menuborder_texture;
  
  FMOD::System* _fmod_system;
  FMOD::Sound* _fmod_music_sound;
  FMOD::Sound* _fmod_slide_sound;
  FMOD::Sound* _fmod_collision_sound;
  FMOD::Sound* _fmod_menu_move_sound;
  FMOD::Sound* _fmod_menu_select_sound;
  FMOD::Channel* _fmod_music_channel;
  FMOD::Sound* _fmod_focus_sound;
  FMOD::Sound* _fmod_select_sound;
  FMOD::Sound* _fmod_impact_sound;
  FMOD::Sound* _fmod_crowd_background_sound;
  FMOD::Channel* _fmod_crowd_background_channel;
  
  typedef std::map<boost::shared_ptr<stone>, boost::shared_ptr<stone_renderer_t> > stone_renderer_map;
  stone_renderer_map _stone_renderers;
};

}

#endif